package com.demo.arch.datapulsedemo.v3_reliable.core;

import com.demo.arch.datapulsedemo.v2_pipeline.core.PipelineContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 上下文存储器
 * 
 * 轻量级实现：使用文件系统存储上下文
 * 如果有Redis，可以替换为Redis实现
 * 
 * @author DataPulse Team
 */
@Slf4j
@Component
public class ContextStorage {

  private static final String STORAGE_DIR = "/tmp/datapulse/contexts";
  private static final String FILE_EXTENSION = ".json";

  /**
   * 保存上下文
   */
  public void save(PipelineContext context) {
    try {
      // 确保目录存在
      ensureDirectoryExists();

      // 序列化上下文
      String json = serializeContext(context);

      // 写入文件
      Path filePath = getFilePath(context.getTaskId());
      Files.writeString(filePath, json);

      log.debug("上下文已保存: {}", filePath);

    } catch (Exception e) {
      log.error("保存上下文失败: {}", context.getTaskId(), e);
    }
  }

  /**
   * 加载上下文
   */
  public PipelineContext load(String taskId) {
    Path filePath = getFilePath(taskId);

    if (!Files.exists(filePath)) {
      log.debug("上下文不存在: {}", taskId);
      return null;
    }

    try {
      String json = Files.readString(filePath);
      PipelineContext context = deserializeContext(json);

      log.debug("上下文已加载: {}", taskId);
      return context;

    } catch (Exception e) {
      log.error("加载上下文失败: {}", taskId, e);
      return null;
    }
  }

  /**
   * 删除上下文
   */
  public void delete(String taskId) {
    Path filePath = getFilePath(taskId);

    try {
      Files.deleteIfExists(filePath);
      log.debug("上下文已删除: {}", taskId);
    } catch (Exception e) {
      log.error("删除上下文失败: {}", taskId, e);
    }
  }

  /**
   * 查询所有失败的任务
   */
  public List<String> findFailedTasks() {
    try {
      ensureDirectoryExists();

      try (Stream<Path> paths = Files.list(Paths.get(STORAGE_DIR))) {
        return paths
            .filter(Files::isRegularFile)
            .filter(path -> path.toString().endsWith(FILE_EXTENSION))
            .map(path -> {
              try {
                String json = Files.readString(path);
                PipelineContext context = deserializeContext(json);

                // 检查是否失败（简单判断：有错误消息）
                if (context.getErrorMessage() != null) {
                  return context.getTaskId();
                }
                return null;
              } catch (Exception e) {
                return null;
              }
            })
            .filter(taskId -> taskId != null)
            .collect(Collectors.toList());
      }
    } catch (Exception e) {
      log.error("查询失败任务失败", e);
      return List.of();
    }
  }

  /**
   * 确保存储目录存在
   */
  private void ensureDirectoryExists() throws IOException {
    Path dir = Paths.get(STORAGE_DIR);
    if (!Files.exists(dir)) {
      Files.createDirectories(dir);
    }
  }

  /**
   * 获取文件路径
   */
  private Path getFilePath(String taskId) {
    return Paths.get(STORAGE_DIR, taskId + FILE_EXTENSION);
  }

  /**
   * 序列化上下文（简单实现）
   * 
   * 注意：实际项目中应使用Jackson或Gson
   */
  private String serializeContext(PipelineContext context) {
    // 简单实现，实际项目中应使用Jackson或Gson
    return "{"
        + "\"taskId\":\"" + context.getTaskId() + "\","
        + "\"reportType\":\"" + context.getReportType() + "\","
        + "\"currentStep\":" + context.getCurrentStep() + ","
        + "\"excelFilePath\":\"" + (context.getExcelFilePath() != null ? context.getExcelFilePath() : "") + "\","
        + "\"emailSuccessCount\":" + (context.getEmailSuccessCount() != null ? context.getEmailSuccessCount() : 0) + ","
        + "\"emailFailCount\":" + (context.getEmailFailCount() != null ? context.getEmailFailCount() : 0) + ","
        + "\"errorMessage\":\"" + (context.getErrorMessage() != null ? context.getErrorMessage() : "") + "\""
        + "}";
  }

  /**
   * 反序列化上下文（简单实现）
   * 
   * 注意：实际项目中应使用Jackson或Gson
   */
  private PipelineContext deserializeContext(String json) {
    // 简单实现，实际项目中应使用Jackson或Gson
    PipelineContext context = new PipelineContext();

    // 提取taskId
    String taskIdPattern = "\"taskId\":\"([^\"]+)\"";
    java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(taskIdPattern);
    java.util.regex.Matcher matcher = pattern.matcher(json);
    if (matcher.find()) {
      context.setTaskId(matcher.group(1));
    }

    // 提取reportType
    String reportTypePattern = "\"reportType\":\"([^\"]+)\"";
    pattern = java.util.regex.Pattern.compile(reportTypePattern);
    matcher = pattern.matcher(json);
    if (matcher.find()) {
      context.setReportType(matcher.group(1));
    }

    // 提取currentStep
    String currentStepPattern = "\"currentStep\":([0-9]+)";
    pattern = java.util.regex.Pattern.compile(currentStepPattern);
    matcher = pattern.matcher(json);
    if (matcher.find()) {
      context.setCurrentStep(Integer.parseInt(matcher.group(1)));
    }

    // 提取excelFilePath
    String excelFilePathPattern = "\"excelFilePath\":\"([^\"]+)\"";
    pattern = java.util.regex.Pattern.compile(excelFilePathPattern);
    matcher = pattern.matcher(json);
    if (matcher.find()) {
      String path = matcher.group(1);
      if (!path.isEmpty()) {
        context.setExcelFilePath(path);
      }
    }

    // 提取errorMessage
    String errorMessagePattern = "\"errorMessage\":\"([^\"]+)\"";
    pattern = java.util.regex.Pattern.compile(errorMessagePattern);
    matcher = pattern.matcher(json);
    if (matcher.find()) {
      String error = matcher.group(1);
      if (!error.isEmpty()) {
        context.setErrorMessage(error);
      }
    }

    return context;
  }
}
